// 123网盘解析文件直连
// 调用方法：await model('api/123dbank').parse("文件分析地址或者文件分享地址key", "密码");

import axios from 'axios';
class dbank {
    async parse(data, code = null) {
        const SHARE_URL_PREFIX = "https://www.123pan.com/s/";
        const FIRST_REQUEST_URL = SHARE_URL_PREFIX + "{key}.html";
        const GET_FILE_INFO_URL =
            "https://www.123pan.com/b/api/share/get?limit=100&next=1&orderBy=file_name&orderDirection=asc" +
            "&shareKey={shareKey}&SharePwd={pwd}&ParentFileId=0&Page=1&event=homeListFile&operateType=1";
        const DOWNLOAD_API_URL = "https://www.123pan.com/b/api/share/download/info?{authK}={authV}";

        // console.log("测试1----：");
        const dataKey = data.replace(SHARE_URL_PREFIX, '');
        const promise = new Promise((resolve, reject) => {
            axios.get(FIRST_REQUEST_URL.replace('{key}', dataKey))
                .then((res) => {
                    const html = res.data;
                    const compile = /window.g_initialProps\s*=\s*(.*);/;
                    const matcher = compile.exec(html);

                    if (!matcher) {
                        reject({
                            code: -1,
                            status: 'Failed',
                            msg: `${dataKey} 正则匹配失败`,
                        });
                        return;
                    }

                    const fileInfoString = matcher[1];
                    const fileInfoJson = JSON.parse(fileInfoString);
                    const resJson = fileInfoJson.res;
                    const resListJson = fileInfoJson.reslist;

                    if (!resJson || resJson.code !== 0) {
                        reject({
                            code: -2,
                            status: 'Failed',
                            msg: `${dataKey} 解析到异常JSON: ${resJson}`,
                        });
                        return;
                    }
                    const shareKey = resJson.data.ShareKey;
                    if (!resListJson || resListJson.code !== 0) {
                        // 加密分享
                        if (code) {
                            axios
                                .get(GET_FILE_INFO_URL.replace('{shareKey}', shareKey).replace('{pwd}', code), {
                                    headers: {
                                        Platform: 'web',
                                        'App-Version': '3',
                                    },
                                })
                                .then((res2) => {
                                    const infoJson = res2.data;
                                    if (infoJson.code !== 0) {
                                        reject({
                                            code: -3,
                                            status: 'Failed',
                                            msg: `状态码异常 ${infoJson}`,
                                        });
                                        return;
                                    }
                                    const getFileInfoJson = infoJson.data.InfoList[0];
                                    getFileInfoJson.ShareKey = shareKey;
                                    this.getDownUrl(resolve, reject, getFileInfoJson);
                                })
                                .catch((error) =>
                                    reject({
                                        code: -4,
                                        status: 'Failed',
                                        msg: `Ye: ${dataKey} ${error}`,
                                    })
                                );
                        } else {
                            reject({
                                code: -5,
                                status: 'Failed',
                                msg: `${dataKey} 该分享需要密码`,
                            });
                        }
                        return;
                    }

                    const reqBodyJson = resListJson.data.InfoList[0];
                    reqBodyJson.ShareKey = shareKey;
                    this.getDownUrl(resolve, reject, reqBodyJson);
                })
                .catch((error) =>
                    reject({
                        code: -6,
                        status: 'Failed',
                        msg: `Ye: ${dataKey} ${error}`,
                    })
                );
        });

        return promise;
    }

    async getDownUrl(resolve, reject, reqBodyJson) {
        const authK = "";
        const authV = "";
        const DOWNLOAD_API_URL =
            "https://www.123pan.com/b/api/share/download/info?{authK}={authV}";

        const jsonObject = {
            ShareKey: reqBodyJson.ShareKey,
            FileID: reqBodyJson.FileId,
            S3keyFlag: reqBodyJson.S3KeyFlag,
            Size: reqBodyJson.Size,
            Etag: reqBodyJson.Etag,
        };


        try {
            const getSign = this.getSign("/b/api/share/download/info");
            // console.log("测试3----：", getSign);
            if (!getSign) {
                reject({
                    code: -7,
                    status: 'Failed',
                    msg: `${ArrayUtils.toString(getSign)}`,
                });
                return;
            }

            axios.post(DOWNLOAD_API_URL.replace("{authK}", getSign[0]).replace("{authV}", getSign[1]), jsonObject, {
                headers: {
                    Platform: 'web',
                    'App-Version': '3',
                },
            })
                .then((res2) => {
                    const downURLJson = res2.data;

                    if (downURLJson.code !== 0) {
                        reject({
                            code: -8,
                            status: 'Failed',
                            msg: `downURLJson返回值异常->${downURLJson}`,
                        });
                        return;
                    }

                    const downURL = downURLJson.data.DownloadURL;
                    const urlParams = this.getURLParams(downURL);
                    const params = urlParams.params;
                    const decodeByte = Buffer.from(params, 'base64');
                    const downUrl2 = decodeByte.toString();

                    axios.get(downUrl2)
                        .then((res3) => {
                            const res3Json = res3.data;
                            if (res3Json.code !== 0) {
                                reject({
                                    code: -9,
                                    status: 'Failed',
                                    msg: `downUrl2返回值异常->${res3Json}`,
                                });
                                return;
                            }
                            resolve({
                                code: 0,
                                status: 'Success',
                                msg: '',
                                data: {
                                    redirect_url: res3Json.data.redirect_url,
                                },
                            });
                        })
                        .catch((error) =>
                            reject({
                                code: -10,
                                status: 'Failed',
                                msg: `Ye: ${JSON.stringify(reqBodyJson)} ${error}`,
                            })
                        );
                })
                .catch((error) =>
                    reject({
                        code: -11,
                        status: 'Failed',
                        msg: `Ye: ${JSON.stringify(reqBodyJson)} ${error}`,
                    })
                );


        } catch (error) {
            reject({
                code: -12,
                status: 'Failed',
                msg: `${error}`,
            });
        }
    }



    getURLParams(url) {
        const urlObj = new URL(url);
        const query = urlObj.searchParams;
        const map = {};

        for (let [key, value] of query.entries()) {
            map[key] = value;
        }

        return map;
    }

    _0x1b5d95(_0x278d1a) {
        var _0x839b57,
            _0x4ed4dc = arguments['length'] > 0x2 && void 0x0 !== arguments[0x2] ? arguments[0x2] : 0x8;
        if (0x0 === arguments['length'])
            return null;
        'object' === typeof _0x278d1a ? _0x839b57 = _0x278d1a : (0xa === ('' + _0x278d1a)['length'] && (_0x278d1a = 0x3e8 * parseInt(_0x278d1a)),
            _0x839b57 = new Date(_0x278d1a));
        var _0xc5c54a = _0x278d1a + 0xea60 * new Date(_0x278d1a)['getTimezoneOffset']()
            , _0x3732dc = _0xc5c54a + 0x36ee80 * _0x4ed4dc;
        return _0x839b57 = new Date(_0x3732dc),
        {
            'y': _0x839b57['getFullYear'](),
            'm': _0x839b57['getMonth']() + 0x1 < 0xa ? '0' + (_0x839b57['getMonth']() + 0x1) : _0x839b57['getMonth']() + 0x1,
            'd': _0x839b57['getDate']() < 0xa ? '0' + _0x839b57['getDate']() : _0x839b57['getDate'](),
            'h': _0x839b57['getHours']() < 0xa ? '0' + _0x839b57['getHours']() : _0x839b57['getHours'](),
            'f': _0x839b57['getMinutes']() < 0xa ? '0' + _0x839b57['getMinutes']() : _0x839b57['getMinutes']()
        };
    }


    _0x4f141a(_0x4075b1) {

        for (var _0x4eddcb = arguments['length'] > 0x1 && void 0x0 !== arguments[0x1] ? arguments[0x1] : 0xa,

            _0x4ee01e = function (_0x3bb99e) {
                var _0x3bb99e = _0x3bb99e['replace'](/\\r\\n/g, '\x5cn');
                for (var _0x585459 = '', _0x15c988 = 0x0; _0x15c988 < _0x3bb99e['length']; _0x15c988++) {
                    var _0x36bb3e = _0x3bb99e['charCodeAt'](_0x15c988);
                    _0x36bb3e < 0x80 ? _0x585459 += String['fromCharCode'](_0x36bb3e) : _0x36bb3e > 0x7f && _0x36bb3e < 0x800 ? (_0x585459 += String['fromCharCode'](_0x36bb3e >> 0x6 | 0xc0),
                        _0x585459 += String['fromCharCode'](0x3f & _0x36bb3e | 0x80)) : (_0x585459 += String['fromCharCode'](_0x36bb3e >> 0xc | 0xe0),
                            _0x585459 += String['fromCharCode'](_0x36bb3e >> 0x6 & 0x3f | 0x80),
                            _0x585459 += String['fromCharCode'](0x3f & _0x36bb3e | 0x80));
                }
                return _0x585459;
            }, _0x2fc680 = function () {
                for (var _0x515c63, _0x361314 = [], _0x4cbdba = 0x0; _0x4cbdba < 0x100; _0x4cbdba++) {
                    _0x515c63 = _0x4cbdba;
                    for (var _0x460960 = 0x0; _0x460960 < 0x8; _0x460960++)
                        _0x515c63 = 0x1 & _0x515c63 ? 0xedb88320 ^ _0x515c63 >>> 0x1 : _0x515c63 >>> 0x1;
                    _0x361314[_0x4cbdba] = _0x515c63;
                }
                return _0x361314;
            },
            _0x4aed86 = _0x2fc680(),
            _0x5880f0 = _0x4ee01e(_0x4075b1),
            _0x492393 = -0x1, _0x25d82c = 0x0;
            _0x25d82c < _0x5880f0['length'];
            _0x25d82c++)

            _0x492393 = _0x492393 >>> 0x8 ^ _0x4aed86[0xff & (_0x492393 ^ _0x5880f0.charCodeAt(_0x25d82c))];
        return _0x492393 = (-0x1 ^ _0x492393) >>> 0x0,
            _0x492393.toString(_0x4eddcb);
    }


    getSign(_0x1e37d5) {
        var _0x4e2d74 = 'web';
        var _0x56f040 = 3;
        var _0x1e2592 = Math.round((new Date().getTime() + 0x3c * new Date().getTimezoneOffset() * 0x3e8 + 28800000) / 0x3e8).toString();
        var key = 'a,d,e,f,g,h,l,m,y,i,j,n,o,p,k,q,r,s,t,u,b,c,v,w,s,z';
        var _0x48562f = Math['round'](0x989680 * Math['random']());

        var _0x2f7dfc;
        var _0x35a889;
        var _0x36f983;
        var _0x3b043d;
        var _0x5bc73b;
        var _0x4b30b2;
        var _0x32399e;
        var _0x25d94e;
        var _0x373490;
        for (var _0x1c540f in (_0x2f7dfc = key.split(','),
            _0x35a889 = this._0x1b5d95(_0x1e2592),
            _0x36f983 = _0x35a889['y'],
            _0x3b043d = _0x35a889['m'],
            _0x5bc73b = _0x35a889['d'],
            _0x4b30b2 = _0x35a889['h'],
            _0x32399e = _0x35a889['f'],
            _0x25d94e = [_0x36f983, _0x3b043d, _0x5bc73b, _0x4b30b2, _0x32399e].join(''),
            _0x373490 = [],
            _0x25d94e))
            _0x373490['push'](_0x2f7dfc[Number(_0x25d94e[_0x1c540f])]);
        var _0x43bdc6;
        var _0x406c4e;
        return _0x43bdc6 = this._0x4f141a(_0x373490['join']('')),
            _0x406c4e = this._0x4f141a(''['concat'](_0x1e2592, '|')['concat'](_0x48562f, '|')['concat'](_0x1e37d5, '|')['concat'](_0x4e2d74, '|')['concat'](_0x56f040, '|')['concat'](_0x43bdc6)),
            [_0x43bdc6, ''['concat'](_0x1e2592, '-')['concat'](_0x48562f, '-')['concat'](_0x406c4e)];
    }
}

export default function (url,pwd = null){
    let dbankClass = new dbank();
    return dbankClass.parse(String(url),pwd);
    
}